﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace TimeMachine.Engine.Metrics.Impl
{
	public class LinesModificationCounter
	{
		private readonly List<string> addedLines = new List<string>();
		private string currentFilename;
		private readonly List<string> removedLines = new List<string>();

		public double LinesChanged { get; private set; }

		public void SetFilename(string filename)
		{
			if(currentFilename != filename)
				FinishChunk();
			currentFilename = filename;
		}

		public void Removed(string line)
		{
			if(line.Trim().Length > 0) removedLines.Add(line);
		}

		public void Added(string line)
		{
			if(line.Trim().Length > 0) addedLines.Add(line);
		}

		public void FinishChunk()
		{
			int i = 0;
			while(i < addedLines.Count && i < removedLines.Count)
			{
				var added = addedLines[i];
				var removed = removedLines[i];
				if(!LittleRefactoring(added, removed) && !SpaceReformat(added, removed)) LinesChanged++;
				i++;
			}
			if(i < addedLines.Count) LinesChanged += addedLines.Count - i;
			addedLines.Clear();
			removedLines.Clear();
		}

		private static bool SpaceReformat(string newLine, string oldLine)
		{
			if(oldLine == null) return false;
			Func<string, string> removeSpaces = s => new string(s.Where(ch => !char.IsWhiteSpace(ch)).ToArray());
			return removeSpaces(newLine) == removeSpaces(oldLine);
		}

		private static bool LittleRefactoring(string newLine, string oldLine)
		{
			if(oldLine == null) return false;
			var separators = new[] { ' ', '\t', '.', '(', ')', '[', ']', ',', '{', '}', ';' };
			string[] newParts = newLine.Split(separators, StringSplitOptions.RemoveEmptyEntries);
			string[] oldParts = oldLine.Split(separators, StringSplitOptions.RemoveEmptyEntries);
			if(newParts.Length != oldParts.Length) return false;
			int count = 0;
			for(int i = 0; i < newParts.Length; i++)
			{
				if(newParts[i] != oldParts[i]) count++;
			}
			return count <= 2;
		}

	}
}